package com.yanghui.agent.agent.springboot.c.interceptor;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.util.JdbcConstants;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yanghui.agent.agent.springboot.c.entity.Entity;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.Configuration;

import java.util.List;
import java.util.Map;

@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class UpdateInterceptor implements Interceptor {

    private static IDynamicFieldStrategy dynamicFieldStrategy;

    static {
        dynamicFieldStrategy = new AbstractDynamicFieldStrategy(){
//            @Override
//            protected List<ParameterMapping> buildInsertParameterMapping(Entity entity, Configuration configuration) {
//                List<ParameterMapping> resultList = Lists.newArrayList();
//                entity.getDynamicFields().forEach((k,v) -> {
//                    ParameterMapping parameterMapping = new ParameterMapping.Builder(configuration,
//                            "dynamicFields." + k,Object.class)
//                            .mode(ParameterMode.IN)
//                            .build();
//                    resultList.add(parameterMapping);
//                });
//                return resultList;
//            }

//            @Override
//            protected List<ParameterMapping> buildUpdateParameterMapping(Entity entity,Configuration configuration) {
//                List<ParameterMapping> resultList = Lists.newArrayList();
//                entity.getDynamicFields().forEach((k,v) -> {
//                    ParameterMapping parameterMapping = new ParameterMapping.Builder(configuration,
//                            "et.dynamicFields." + k,Object.class)
//                            .mode(ParameterMode.IN)
//                            .build();
//                    resultList.add(parameterMapping);
//                });
//                return resultList;
//            }

            @Override
            protected void visit(MySqlInsertStatement x, Entity entity) {
                entity.getDynamicFields().forEach((k,v) -> {
                    x.getColumns().add(SQLUtils.toMySqlExpr(k));
                    x.getValues().addValue(SQLUtils.toMySqlExpr(v.toString()));
                });
            }

            @Override
            protected void visit(MySqlUpdateStatement x, Entity entity) {
                entity.getDynamicFields().forEach((k,v) -> {
                    x.getItems().add(SQLUtils.toUpdateSetItem(k + " = " + v,Object.class.getTypeName()));
                });
            }
        };
    }

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        MappedStatement mappedStatement = (MappedStatement) args[0];
        dynamicFieldStrategy.execute(mappedStatement,args);
        return invocation.proceed();
    }
}
